
/*
This file is part of MJIN2.

Copyright (C) 2012-2013 Opensource Game Studio

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

#ifndef MJIN2_INPUT_LISTENER_H
#define MJIN2_INPUT_LISTENER_H

#include <mjin2/Common.h>
#include <mjin2/TypeDefs.h>

namespace mjin2
{

//! Key enum including keys, mouse buttons and mouse scroll.
enum INPUT
{
    INPUT_SCROLL_NONE         = -25,
    INPUT_SCROLL_LEFT         = -24,
    INPUT_SCROLL_RIGHT        = -23,
    INPUT_SCROLL_UP           = -22,
    INPUT_SCROLL_DOWN         = -21,

    INPUT_MOUSE_MOVE          = -15,
    INPUT_MOUSE_BUTTON_LEFT   = -14,
    INPUT_MOUSE_BUTTON_MIDDLE = -13,
    INPUT_MOUSE_BUTTON_NONE   = -12,
    INPUT_MOUSE_BUTTON_RIGHT  = -11,

    INPUT_KEY_SPACE           = 0x20,

    INPUT_KEY_0               = 48,
    INPUT_KEY_1               = 49,
    INPUT_KEY_2               = 50,
    INPUT_KEY_3               = 51,
    INPUT_KEY_4               = 52,
    INPUT_KEY_5               = 53,
    INPUT_KEY_6               = 54,
    INPUT_KEY_7               = 55,
    INPUT_KEY_8               = 56,
    INPUT_KEY_9               = 57,
    INPUT_KEY_A               = 97,
    INPUT_KEY_B               = 98,
    INPUT_KEY_C               = 99,
    INPUT_KEY_D               = 100,
    INPUT_KEY_E               = 101,
    INPUT_KEY_F               = 102,
    INPUT_KEY_G               = 103,
    INPUT_KEY_H               = 104,
    INPUT_KEY_I               = 105,
    INPUT_KEY_J               = 106,
    INPUT_KEY_K               = 107,
    INPUT_KEY_L               = 108,
    INPUT_KEY_M               = 109,
    INPUT_KEY_N               = 110,
    INPUT_KEY_O               = 111,
    INPUT_KEY_P               = 112,
    INPUT_KEY_Q               = 113,
    INPUT_KEY_R               = 114,
    INPUT_KEY_S               = 115,
    INPUT_KEY_T               = 116,
    INPUT_KEY_U               = 117,
    INPUT_KEY_V               = 118,
    INPUT_KEY_W               = 119,
    INPUT_KEY_X               = 120,
    INPUT_KEY_Y               = 121,
    INPUT_KEY_Z               = 122,

    INPUT_KEY_EXCLAIM         = 0x21,
    INPUT_KEY_QUOTEDBL        = 0x22,
    INPUT_KEY_HASH            = 0x23,
    INPUT_KEY_DOLLAR          = 0x24,
    INPUT_KEY_AMPERSAND       = 0x26,
    INPUT_KEY_QUOTE           = 0x27,
    INPUT_KEY_LEFTPAREN       = 0x28,
    INPUT_KEY_RIGHTPAREN      = 0x29,
    INPUT_KEY_ASTERISK        = 0x2A,
    INPUT_KEY_PLUS            = 0x2B,
    INPUT_KEY_COMMA           = 0x2C,
    INPUT_KEY_MINUS           = 0x2D,
    INPUT_KEY_PERIOD          = 0x2E,
    INPUT_KEY_SLASH           = 0x2F,
    INPUT_KEY_COLON           = 0x3A,
    INPUT_KEY_SEMICOLON       = 0x3B,
    INPUT_KEY_LESS            = 0x3C,
    INPUT_KEY_EQUALS          = 0x3D,
    INPUT_KEY_GREATER         = 0x3E,
    INPUT_KEY_QUESTION        = 0x3F,
    INPUT_KEY_AT              = 0x40,
    INPUT_KEY_LEFTBRACKET     = 0x5B,
    INPUT_KEY_BACKSLASH       = 0x5C,
    INPUT_KEY_RIGHTBRACKET    = 0x5D,
    INPUT_KEY_CARET           = 0x5E,
    INPUT_KEY_UNDERSCORE      = 0x5F,
    INPUT_KEY_BACKQUOTE       = 0x60,

    INPUT_KEY_BACKSPACE       = 0xFF08,        /* back space, back char */
    INPUT_KEY_TAB             = 0xFF09,
    INPUT_KEY_LINEFEED        = 0xFF0A,        /* Linefeed, LF */
    INPUT_KEY_CLEAR           = 0xFF0B,
    INPUT_KEY_RETURN          = 0xFF0D,        /* Return, enter */
    INPUT_KEY_PAUSE           = 0xFF13,        /* Pause, hold */
    INPUT_KEY_SCROLL_LOCK     = 0xFF14,
    INPUT_KEY_SYS_REQ         = 0xFF15,
    INPUT_KEY_ESCAPE          = 0xFF1B,
    INPUT_KEY_DELETE          = 0xFFFF,        /* Delete, rubout */

    /* Cursor control & motion */
    INPUT_KEY_HOME            = 0xFF50,
    INPUT_KEY_LEFT            = 0xFF51,        /* Move left, left arrow */
    INPUT_KEY_UP              = 0xFF52,        /* Move up, up arrow */
    INPUT_KEY_RIGHT           = 0xFF53,        /* Move right, right arrow */
    INPUT_KEY_DOWN            = 0xFF54,        /* Move down, down arrow */
    INPUT_KEY_PRIOR           = 0xFF55,        /* Prior, previous */
    INPUT_KEY_PAGE_UP         = 0xFF55,
    INPUT_KEY_NEXT            = 0xFF56,        /* Next */
    INPUT_KEY_PAGE_DOWN       = 0xFF56,
    INPUT_KEY_END             = 0xFF57,        /* EOL */
    INPUT_KEY_BEGIN           = 0xFF58,        /* BOL */

    /* Misc Functions */
    INPUT_KEY_SELECT          = 0xFF60,        /* Select, mark */
    INPUT_KEY_PRINT           = 0xFF61,
    // I don't know why MinGW doesn't like it.
//#ifndef WIN32
    //INPUT_KEY_EXECUTE         = 0xFF62,        /* Execute, run, do */
//#endif
    INPUT_KEY_INSERT          = 0xFF63,        /* Insert, insert here */
    INPUT_KEY_UNDO            = 0xFF65,        /* Undo, oops */
    INPUT_KEY_REDO            = 0xFF66,        /* redo, again */
    INPUT_KEY_MENU            = 0xFF67,        /* VK_APPS on Windows, the context-menu key */
    INPUT_KEY_FIND            = 0xFF68,        /* Find, search */
    INPUT_KEY_CANCEL          = 0xFF69,        /* Cancel, stop, abort, exit */
    INPUT_KEY_HELP            = 0xFF6A,        /* Help */
    INPUT_KEY_BREAK           = 0xFF6B,
    INPUT_KEY_MODE_SWITCH     = 0xFF7E,        /* Character set switch */
    INPUT_KEY_SCRIPT_SWITCH   = 0xFF7E,        /* Alias for mode_switch */
    INPUT_KEY_NUM_LOCK        = 0xFF7F,

    /* Keypad Functions, keypad numbers cleverly chosen to map to ascii */
    INPUT_KEY_KP_SPACE        = 0xFF80,        /* space */
    INPUT_KEY_KP_TAB          = 0xFF89,
    INPUT_KEY_KP_ENTER        = 0xFF8D,        /* enter */
    INPUT_KEY_KP_F1           = 0xFF91,        /* PF1, KP_A, ... */
    INPUT_KEY_KP_F2           = 0xFF92,
    INPUT_KEY_KP_F3           = 0xFF93,
    INPUT_KEY_KP_F4           = 0xFF94,
    INPUT_KEY_KP_HOME         = 0xFF95,
    INPUT_KEY_KP_LEFT         = 0xFF96,
    INPUT_KEY_KP_UP           = 0xFF97,
    INPUT_KEY_KP_RIGHT        = 0xFF98,
    INPUT_KEY_KP_DOWN         = 0xFF99,
    INPUT_KEY_KP_PRIOR        = 0xFF9A,
    INPUT_KEY_KP_PAGE_UP      = 0xFF9A,
    INPUT_KEY_KP_NEXT         = 0xFF9B,
    INPUT_KEY_KP_PAGE_DOWN    = 0xFF9B,
    INPUT_KEY_KP_END          = 0xFF9C,
    INPUT_KEY_KP_BEGIN        = 0xFF9D,
    INPUT_KEY_KP_INSERT       = 0xFF9E,
    INPUT_KEY_KP_DELETE       = 0xFF9F,
    INPUT_KEY_KP_EQUAL        = 0xFFBD,        /* equals */
    INPUT_KEY_KP_MULTIPLY     = 0xFFAA,
    INPUT_KEY_KP_ADD          = 0xFFAB,
    INPUT_KEY_KP_SEPARATOR    = 0xFFAC,       /* separator, often comma */
    INPUT_KEY_KP_SUBTRACT     = 0xFFAD,
    INPUT_KEY_KP_DECIMAL      = 0xFFAE,
    INPUT_KEY_KP_DIVIDE       = 0xFFAF,

    INPUT_KEY_KP_0            = 0xFFB0,
    INPUT_KEY_KP_1            = 0xFFB1,
    INPUT_KEY_KP_2            = 0xFFB2,
    INPUT_KEY_KP_3            = 0xFFB3,
    INPUT_KEY_KP_4            = 0xFFB4,
    INPUT_KEY_KP_5            = 0xFFB5,
    INPUT_KEY_KP_6            = 0xFFB6,
    INPUT_KEY_KP_7            = 0xFFB7,
    INPUT_KEY_KP_8            = 0xFFB8,
    INPUT_KEY_KP_9            = 0xFFB9,

    INPUT_KEY_F1              = 0xFFBE,
    INPUT_KEY_F2              = 0xFFBF,
    INPUT_KEY_F3              = 0xFFC0,
    INPUT_KEY_F4              = 0xFFC1,
    INPUT_KEY_F5              = 0xFFC2,
    INPUT_KEY_F6              = 0xFFC3,
    INPUT_KEY_F7              = 0xFFC4,
    INPUT_KEY_F8              = 0xFFC5,
    INPUT_KEY_F9              = 0xFFC6,
    INPUT_KEY_F10             = 0xFFC7,
    INPUT_KEY_F11             = 0xFFC8,
    INPUT_KEY_F12             = 0xFFC9,
    INPUT_KEY_F13             = 0xFFCA,
    INPUT_KEY_F14             = 0xFFCB,
    INPUT_KEY_F15             = 0xFFCC,
    INPUT_KEY_F16             = 0xFFCD,
    INPUT_KEY_F17             = 0xFFCE,
    INPUT_KEY_F18             = 0xFFCF,
    INPUT_KEY_F19             = 0xFFD0,
    INPUT_KEY_F20             = 0xFFD1,
    INPUT_KEY_F21             = 0xFFD2,
    INPUT_KEY_F22             = 0xFFD3,
    INPUT_KEY_F23             = 0xFFD4,
    INPUT_KEY_F24             = 0xFFD5,
    INPUT_KEY_F25             = 0xFFD6,
    INPUT_KEY_F26             = 0xFFD7,
    INPUT_KEY_F27             = 0xFFD8,
    INPUT_KEY_F28             = 0xFFD9,
    INPUT_KEY_F29             = 0xFFDA,
    INPUT_KEY_F30             = 0xFFDB,
    INPUT_KEY_F31             = 0xFFDC,
    INPUT_KEY_F32             = 0xFFDD,
    INPUT_KEY_F33             = 0xFFDE,
    INPUT_KEY_F34             = 0xFFDF,
    INPUT_KEY_F35             = 0xFFE0,

    /* Modifiers */
    INPUT_KEY_SHIFT_L         = 0xFFE1,        /* Left shift */
    INPUT_KEY_SHIFT_R         = 0xFFE2,        /* Right shift */
    INPUT_KEY_CONTROL_L       = 0xFFE3,        /* Left control */
    INPUT_KEY_CONTROL_R       = 0xFFE4,        /* Right control */
    INPUT_KEY_CAPS_LOCK       = 0xFFE5,        /* Caps lock */
    INPUT_KEY_SHIFT_LOCK      = 0xFFE6,        /* Shift lock */

    INPUT_KEY_META_L          = 0xFFE7,        /* Left meta */
    INPUT_KEY_META_R          = 0xFFE8,        /* Right meta */
    INPUT_KEY_ALT_L           = 0xFFE9,        /* Left alt */
    INPUT_KEY_ALT_R           = 0xFFEA,        /* Right alt */
    INPUT_KEY_SUPER_L         = 0xFFEB,        /* Left super */
    INPUT_KEY_SUPER_R         = 0xFFEC,        /* Right super */
    INPUT_KEY_HYPER_L         = 0xFFED,        /* Left hyper */
    INPUT_KEY_HYPER_R         = 0xFFEE         /* Right hyper */
};

struct InputEvent
{
    InputEvent(s32 input,
               s32 unmodifiedInput,
               s32 x,
               s32 y,
               s32 yi,
               bool press): input(input),
                            unmodifiedInput(unmodifiedInput),
                            x(x),
                            y(y),
                            yi(yi),
                            press(press) { }
    s32 input;
    s32 unmodifiedInput;
    s32 x;
    //! Goes from top to bottom.
    s32 y;
    //! Inverted Y (OSG original Y, goes from bottom to top)
    s32 yi;
    //! true = press, false = release
    bool press;
};

//! Inherit this class to be able to accept Window input.
class InputListener
{
        DISALLOW_COPY_AND_ASSIGN(InputListener);
    public:
        InputListener() throw () { }
        virtual ~InputListener() throw () { }

        //! You can check both input and unmodifiedInput against INPUT enum.
        //! input might be different for different locales.
        //! unmodifiedInput is always the same, e.g., it's always 'a' if you press the physical 'A' button with or without shift, or when you're using different locale.
        virtual void onInput(const InputEvent &e) throw () { }
};

} // namespace mjin2

#endif // MJIN2_INPUT_LISTENER_H

